return {

  {
    "mfussenegger/nvim-lint",
    opts = {},
    config = function()
      local find_package_json_ancestor = require("lspconfig.util").find_package_json_ancestor
      local supported_filetypes = {
        "javascript",
        "javascriptreact",
        "typescript",
        "typescriptreact",
        "javascript.jsx",
        "typescript.tsx",
      }

      local severity = {
        vim.diagnostic.severity.WARN,
        vim.diagnostic.severity.ERROR,
      }

      local binary_name = "eslint"

      require('lint').linters.eslint = {
        cmd = function()
          return require 'next.utils'.find_from_node_modules(binary_name) or binary_name
        end,
        stdin = true,        -- or false if it doesn't support content input via stdin. In that case the filename is automatically added to the arguments.
        append_fname = true, -- Automatically append the file name to `args` if `stdin = false` (default: true)

        args = {
          '--report-unused-disable-directives',
          '--format',
          'json',
          '--stdin',
          '--stdin-filename',
          function() return vim.api.nvim_buf_get_name(0) end,
        },
        stream = 'both',        -- ('stdout' | 'stderr' | 'both') configure the stream to which the linter outputs the linting result.
        ignore_exitcode = true, -- set this to true if the linter exits with a code != 0 and that's considered normal.
        env = nil,              -- custom environment table to use with the external process. Note that this replaces the *entire* environment, it is not additive.
        parser = function(output, bufnr, linter_cwd)
          -- vim.print(linter_cwd)
          local trimmed_output = vim.trim(output)
          if trimmed_output == "" then
            return {}
          end
          local decode_opts = { luanil = { object = true, array = true } }
          local ok, data = pcall(vim.json.decode, output, decode_opts)
          if string.find(trimmed_output, "No ESLint configuration found") then
            vim.notify_once(trimmed_output, vim.log.levels.WARN)
            return {
              bufnr = bufnr,
              lnum = 0,
              col = 0,
              message = trimmed_output,
            }
          end
          if not ok then
            return {
              {
                bufnr = bufnr,
                lnum = 0,
                col = 0,
                message = "Could not parse linter output due to: " .. data .. "\noutput: " .. output
              }
            }
          end


          -- See https://eslint.org/docs/latest/use/formatters/#json
          local diagnostics = {}
          for _, result in ipairs(data or {}) do
            for _, msg in ipairs(result.messages or {}) do
              table.insert(diagnostics, {
                lnum = msg.line and (msg.line - 1) or 0,
                end_lnum = msg.endLine and (msg.endLine - 1) or nil,
                col = msg.column and (msg.column - 1) or 0,
                end_col = msg.endColumn and (msg.endColumn - 1) or nil,
                message = msg.message,
                code = msg.ruleId,
                severity = severity[msg.severity],
                source = msg.ruleId and '[' .. binary_name .. '] ' .. msg.ruleId or binary_name
              })
            end
          end
          return diagnostics
        end
      }
      for _, ft in ipairs(supported_filetypes) do
        require('lint').linters_by_ft[ft] = { 'eslint' }
      end

      local function get_working_directory()
        local startpath = vim.fn.expand('%')
        return find_package_json_ancestor(startpath)
      end

      local function augroup(name)
        return vim.api.nvim_create_augroup("lazyvim_" .. name, { clear = true })
      end
      -- vim.cmd [[ au BufWritePost * lua require('lint').try_lint() ]]
      vim.api.nvim_create_autocmd({ "InsertLeave", "TextChanged" }, {
        group = augroup('lint'),
        pattern = { "*.js", "*.jsx", "*.ts", "*.tsx" },

        callback = function(opt)
          local stat = vim.uv.fs_stat(vim.api.nvim_buf_get_name(opt.buf))
          -- vim.print('buf ' .. opt.buf .. ' ' .. stat.size)
          if stat.size > 100000 then return end
          local cwd = get_working_directory()
          -- try_lint without arguments runs the linters defined in `linters_by_ft`
          -- for the current filetype
          require("lint").try_lint('eslint', {
            cwd = cwd
          })

          -- You can call `try_lint` with a linter name or a list of names to always
          -- run specific linters, independent of the `linters_by_ft` configuration
          -- require("lint").try_lint("cspell")
        end,
      })
    end
  },

}
